using System.Collections.Generic;
using GameFramework;
using GameFramework.ObjectPool;
using StarForce.Manager;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace StarForce
{

    /// <summary>
    /// 三消游戏小方块组件
    /// </summary>
    public class EliminateComponent : GameFrameworkComponent
    {


        /// <summary>
        /// 方块Item
        /// </summary>
        [SerializeField] private EliminateItem m_EliminateItem = null;

        /// <summary>
        /// 生成小方块的父节点
        /// </summary>
        [SerializeField] private Transform m_EliminateInstanceRoot = null;

        /// <summary>
        /// 对象池容量
        /// </summary>
        [SerializeField] private int m_InstancePoolCapacity = 16;

        /// <summary>
        /// 对象池
        /// </summary>
        private IObjectPool<EliminateItemObject> m_EliminateItemObjectPool;

        /// <summary>
        /// 当前显示的方块Item
        /// </summary>
        private List<EliminateItem> m_ActiveEliminateItems;

        public List<EliminateItem> ActiveEliminateItems
        {
            get { return m_ActiveEliminateItems; }
            set { m_ActiveEliminateItems = value; }
        }

        /// <summary>
        /// 缓存的画布
        /// </summary>
        private Canvas m_CachedCanvas;

        private void Start()
        {
            if (m_EliminateInstanceRoot == null)
            {
                Log.Error("You must set instance root first.");
                return;
            }

            m_CachedCanvas = m_EliminateInstanceRoot.GetComponent<Canvas>();
            m_EliminateItemObjectPool =
                GameEntry.ObjectPool.CreateSingleSpawnObjectPool<EliminateItemObject>("Eliminate",
                    m_InstancePoolCapacity);
            m_ActiveEliminateItems = new List<EliminateItem>();
        }

        /// <summary>
        /// 设置数组长度
        /// </summary>
        /// <param name="length"></param>
        public void SetListLength(int length)
        {
            m_ActiveEliminateItems = new List<EliminateItem>(length);
        }

        /// <summary>
        /// 生成一个新的方块
        /// </summary>
        /// <returns></returns>
        private EliminateItem Create()
        {
            EliminateItem eliminateItem = null;

            EliminateItemObject eliminateItemObject = m_EliminateItemObjectPool.Spawn();

            if (eliminateItemObject != null)
            {
                //对象池中有对象 直接取出
                eliminateItem = (EliminateItem) eliminateItemObject.Target;
            }
            else
            {
                //对象池中没有数据  重新生成
                //否则新生成一个对象
                eliminateItem = Instantiate(m_EliminateItem);
                Transform transform = eliminateItem.GetComponent<Transform>();
                transform.SetParent(m_EliminateInstanceRoot);
                transform.localScale = Vector3.one;
                m_EliminateItemObjectPool.Register(EliminateItemObject.Create(eliminateItem), true);
            }

            return eliminateItem;
        }

        /// <summary>
        /// 展示一个方块
        /// </summary>
        /// <param name="data"></param>
        public void Show(EliminateItemData data)
        {
            EliminateItem eliminateItem = Create();
            m_ActiveEliminateItems.Add(eliminateItem);
            eliminateItem.Init(data);
        }

        /// <summary>
        /// 隐藏一个方块
        /// </summary>
        /// <param name="item"></param>
        public void Hidden(EliminateItem item)
        {
            item.Reset();
            m_ActiveEliminateItems.Remove(item);
            m_EliminateItemObjectPool.Unspawn(item);
        }

        /// <summary>
        /// 清除全部
        /// </summary>
        public void ClearAll()
        {
            for (int i = m_ActiveEliminateItems.Count; i > 0; i--)
            {
                Hidden(m_ActiveEliminateItems[i - 1]);
            }
        }

        /// <summary>
        /// 交换两个方块
        /// </summary>
        /// <param name="eliminateItemA"></param>
        /// <param name="eliminateItemB"></param>
        /// <returns></returns>
        public void ExChange(EliminateItem eliminateItemA, EliminateItem eliminateItemB)
        {
            if (eliminateItemA == null || eliminateItemB == null)
            {
                return;
            }

            Vector3 cur = eliminateItemB.transform.localPosition;

            eliminateItemB.transform.localPosition = eliminateItemA.transform.localPosition;

            eliminateItemA.transform.localPosition = cur;

            //todo 交换位置后 判断是否可以消除  可以消除消除 不可以消除 返回之前的位置

            int curPoa = eliminateItemB.Pos;
            eliminateItemB.Exchange(eliminateItemA.Pos);
            eliminateItemA.Exchange(curPoa);


            bool checkHorizontalA = EliminateInspectManager.Instance.CheckHorizontal(eliminateItemA);      
            bool checkVerticalA = EliminateInspectManager.Instance.CheckVertical(eliminateItemA);      
            
            bool checkHorizontalB = EliminateInspectManager.Instance.CheckHorizontal(eliminateItemB);      
            bool checkVerticalB = EliminateInspectManager.Instance.CheckVertical(eliminateItemB);     

//            if (!CheckTop(eliminateItemB) && !CheckBottom(eliminateItemB) && !CheckRight(eliminateItemB)  && !CheckLeft(eliminateItemB) &&
//                !CheckTop(eliminateItemA) && !CheckBottom(eliminateItemA) && !CheckRight(eliminateItemA)  && !CheckLeft(eliminateItemA))
            if(!checkHorizontalA && !checkVerticalA && !checkHorizontalB && !checkVerticalB)
            {
                //todo 都没有消除 回原位置

                Vector3 cur1 = eliminateItemB.transform.localPosition;

                eliminateItemB.transform.localPosition = eliminateItemA.transform.localPosition;

                eliminateItemA.transform.localPosition = cur1;

                //todo 交换位置后 判断是否可以消除  可以消除消除 不可以消除 返回之前的位置

                int curPoa1 = eliminateItemB.Pos;
                eliminateItemB.Exchange(eliminateItemA.Pos);
                eliminateItemA.Exchange(curPoa1);

                Log.Info("没有可消除元素");
            }
            else
            {
                EliminateInspectManager.Instance.ImplementEliminateCommand();
            }
        }

        /// <summary>
        /// 隐藏同类方块
        /// </summary>
        /// <param name="pos"></param>
        public void ClearItem(List<int> pos)
        {
            for (int i = 0; i < pos.Count; i++)
            {
                for (int j = 0; j < m_ActiveEliminateItems.Count; j++)
                {
                    if (m_ActiveEliminateItems[j].Pos == pos[i])
                    {
                        GameEntry.Eliminate.Hidden(m_ActiveEliminateItems[j]); 
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 获取上一个Item
        /// </summary>
        /// <param name="index"></param>
        public EliminateItem GetTopItem(int index)
        {
            if (index % Constant.EliminateGameConfig.VCount != 0)
            {
                return GetItem(index - 1);
            }

            return null;
        }

        /// <summary>
        /// 获取下方item
        /// </summary>
        /// <param name="index"></param>
        public EliminateItem GetBottomItem(int index)
        {
            if ((index+1) % Constant.EliminateGameConfig.VCount!= 0)
            {
                return GetItem(index + 1);
            }

            return null;
        }
        
        /// <summary>
        /// 获取左侧Item
        /// </summary>
        /// <param name="index"></param>
        public EliminateItem GetLeftItem(int index)
        {
            if (index < Constant.EliminateGameConfig.VCount)
            {
                return null;
            }
            return GetItem(index - Constant.EliminateGameConfig.VCount);
        }

        /// <summary>
        /// 获取右侧item
        /// </summary>
        /// <param name="index"></param>
        public EliminateItem GetRightItem(int index)
        {
            if (index > Constant.EliminateGameConfig.VCount * (Constant.EliminateGameConfig.HCount-1) -1)
            {
                return null;
            }
            return GetItem(index + Constant.EliminateGameConfig.VCount);
        }

        /// <summary>
        /// 根据位置获取Item
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public EliminateItem GetItem(int pos)
        {
            for (int i = 0; i < m_ActiveEliminateItems.Count; i++)
            {
                if (m_ActiveEliminateItems[i].Pos == pos)
                {
                    return m_ActiveEliminateItems[i];
                }
            }

            return null;
        }

    }
}